package com.troyhigh.njrotc.admintracker;

import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.sql.Date;
import java.io.*;

//Random: Record 205: 1231410899727, is the last pre output record.

/**
 * The class that implements AdminTracker in the command line.
 * [+] Rapid data entry [-] Difficult to use
 * 
 * @author Quan Nguyen
 * @version 25-December-2008
 */
public class ATCommandLine
{
    private static AdminTracker admintracker;
    private static Scanner scanner;
    
    private static final String SEPARATOR = File.separator;
    private static final String HELP = "docs" + SEPARATOR + "help";
    private static final String SCRIPTS = "scripts";
    private static final String OUTPUT = "output";
    private static final String BACKUP = "library"+SEPARATOR+"backup";

    public static void main(String[] args)
    {
        System.out.println("[init] Welcome to AdminTracker, the command line edition!");
        System.out.println("[date] The date is: " + (new java.util.Date()).toString());
        System.out.println("[init] Created by BRO Quan Nguyen, c/o 2010!");
        System.out.println("[init] Type \"help\" for more information.");
        System.out.println("[init] Initializing AdminTracker...");
        admintracker = new AdminTracker();
        scanner = new Scanner(System.in);
        System.out.println("[init] AdminTracker instance created.");
        //Menu's don't work. ;_; They're not practical.
        do
        {
            System.out.print("[prompt] [AdminTracker> ");
        }
        while (getInstruction());
        System.out.println("[term] AdminTracker session terminating...");
        admintracker.disconnect();
        System.out.println("[term] AdminTracker session disconnected.");
        System.out.println("[term] Bye!");
    }
    
    private static boolean getInstruction()
    {
        String input = (scanner.nextLine()).trim();
        if(input.equals("quit") || input.equals("exit"))
        {
            return false;
        }
        else if(input.equals(""))
        {
            return true;
        }
        parseInstruction(input);
        return true;
    }
    
    private static void parseInstruction(String input)
    {
        StringTokenizer tokens = new StringTokenizer(input, ";");
        while(tokens.hasMoreElements())
        {
            String line = tokens.nextToken();
            line.replace("['\"]", ""); //A regex that replaces single/married quotes
            try
            {
                String command = line;
                String[] args = { };
                String trimmed = line.trim();
                if(line.indexOf(" ") != -1)
                {
                    int idx = line.indexOf(" ");
                    command = trimmed.substring(0, idx);
                    args = trimmed.substring(idx).split(",");
                    command = command.trim();
                    for(int i = 0; i < args.length; i++)
                    {
                        args[i] = args[i].trim();
                    }
                }
                interpretInstruction(command, args);
            }
            catch (RuntimeException e)
            {
                System.out.println("[error] Syntax error for: \"" + line + "\"");
                System.out.println("[error] " + e.getMessage());
            }
        }
    }
    
    private static void interpretInstruction(String command, String[] args)
    {
        if(command.equals("restart"))
        {
            restart();
        }
        else if(command.equals("crash"))
        {
            crash();
        }
        else if(command.equals("help"))
        {
            help(args);
        }
        else if(command.equals("run"))
        {
            run(args);
        }
        else if(command.equals("commit"))
        {
            commit();
        }
        else if(command.equals("backup"))
        {
            backup();
        }
        else if(command.equals("restore"))
        {
            restore();
        }
        else if(command.equals("useBackup"))
        {
            useBackup();
        }
        else if(command.equals("echo"))
        {
            echo(args);
        }
        else if(command.equals("createCadet"))
        {
            createCadet(args);
        }
        else if(command.equals("createEvent"))
        {
            createEvent(args);
        }
        else if(command.equals("getCadets"))
        {
            getCadets();
        }
        else if(command.equals("getEvents"))
        {
            getEvents();
        }
        else if(command.equals("getCadet"))
        {
            getCadet(findCadet(args));
        }
        else if(command.equals("getEvent"))
        {
            getEvent(findEvent(args));
        }
        else if(command.equals("removeCadet"))
        {
            removeCadet(findCadet(args));
        }
        else if(command.equals("removeEvent"))
        {
            removeEvent(findEvent(args));
        }
        else if(command.equals("setRibbon"))
        {
            if(args.length >= 25) //one line entry
                setRibbon(args);
            else
                setRibbon(findCadet(args));
        }
        else if(command.equals("input"))
        {
            input(findEvent(args));
        }
        else if(command.equals("insert"))
        {
            insert(args);
        }
        else if(command.equals("outputAwards"))
        {
            outputAwards();
        }
        else if(command.equals("previewAwards"))
        {
            previewAwards();
        }
        else if(command.equals("convertDate"))
        {
            convertDate(args);
        }
        else if(command.equals("dumpRibbons"))
        {
            if(args.length > 0 && !args.equals(""))
                dumpRibbons(args[0]);
            else
                dumpRibbons(System.currentTimeMillis()+"");
        }
        else if(command.equals("dumpEvents"))
        {
            if(args.length > 0 && !args.equals(""))
                dumpEvents(args[0]);
            else
                dumpEvents(System.currentTimeMillis()+"");
        }
        else if(command.equals("resetSemester"))
        {
            resetSemester();
        }
        else
        {
            System.out.println("[error] Command not found.");
        }
    }
    
    private static void restart()
    {
        System.out.print("[restart] Are you sure you want to restart? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            admintracker.disconnect();
            System.out.println("[restart] AdminTracker restarting...");
            admintracker = new AdminTracker();
            System.out.println("[restart] New AdminTracker instance created.");
        }
    }
    
    private static void crash()
    {
        System.out.println("[crash] This is a developer's feature that allows");
        System.out.println("[crash] you to terminate the program without saving");
        System.out.println("[crash] data to your databases.");
        System.out.println("[crash] Are you sure you want to crash? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            System.exit(0);
        }
    }
    
    private static void help(String[] args)
    {
        String load = "help";
        if(args.length >= 1 && args[0].equals("files"))
        {
            File d = new File(HELP);
            File[] fs = d.listFiles();
            for(int i = 0; i < fs.length; i++)
            { 
                System.out.println("[help files] " + i + ". " + fs[i].getName());
            }
        }
        else
        {
            if(args.length >= 1)
                load += "-" + args[0];
            load += ".ath";
            System.out.println("[help] Loading help for " + load);        
            try
            {
                BufferedReader helpReader = new BufferedReader(new FileReader(HELP + SEPARATOR + load));
                String line = helpReader.readLine();
                do
                {
                    System.out.println("[" + load + "] " + line);
                    line = helpReader.readLine();
                } while (line != null);
            }
            catch (IOException e)
            {
                System.out.println("[help error] File not found.");
            }
        }
    }
    
    private static void run(String[] args)
    {
        if(args.length == 0)
        {
            String arg[] = {"run"};
            help(arg);
        }
        else
        {
            try
            {
                String load = args[0].trim();
                BufferedReader runReader = new BufferedReader(new FileReader(SCRIPTS + SEPARATOR + load + ".atb"));
                ArrayList<String> commandList = new ArrayList<String>();
                String line = runReader.readLine();
                System.out.println("[script] Reading file: " + load);
                do
                {
                    System.out.println("[script] " + line);
                    commandList.add(line);
                    line = runReader.readLine();
                } while (line != null);
                System.out.print("[prompt] [Do you want to run this file? (Y|N)> ");
                String choice = scanner.nextLine();
                if(choice.equals("Y"))
                {
                    for(String s : commandList)
                    {
                        parseInstruction(s);
                    }
                }
            }
            catch (IOException e)
            {
                System.out.println("[run error] File not found.");
            } 
        }
    }
    
    private static void commit()
    {
        admintracker.commit();
    }
    
    private static void backup()
    {
        System.out.println("[backup] Performing manual backup...");
        admintracker.backup();
    }
    
    private static void restore()
    {
        try
        {
            File d = new File(BACKUP);
            File[] fs = d.listFiles();
            for(int i = 0; i < fs.length; i++)
            { 
                System.out.println("[available backups] " + i + ". " + fs[i].getName());
            }
            System.out.println("[restore] Which backup?> ");
            String line = scanner.nextLine();
            if(line.matches("\\d*\\d"))
            {
                admintracker.restore(line);
            }
            else
            {
                System.out.println("[error] Not a valid backup directory.");
            }
            
        }
        catch(Exception e)
        {
            System.out.println("[error] Error in restoring from backup.");
        }
    }
    
    private static void useBackup()
    {
        System.out.println("[use backup] Are you sure you want to overwrite");
        System.out.println("[use backup] the data you have currently stored");
        System.out.println("[use backup] with data from the backup? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            admintracker.copyBackup();
        }
    }
    
    private static void echo(String[] args)
    {
        for(String s : args)
            System.out.println("[echo] " + s);
    }
    
    private static void createCadet(String[] args)
    {
        try
        {
            String[] find = {args[3]};
            if(findCadet(find) != null) //They found an ID, and it returned a cadet.
            {
                System.out.println("[error] Cadet already exists!");
                return;
            }
            int p = Integer.parseInt(args[0]);
            String l = args[1];
            String f = args[2];
            int i = Integer.parseInt(args[3]);
            char g = args[4].charAt(0);
            int r = Integer.parseInt(args[5]);
            int n = Integer.parseInt(args[6]);
            admintracker.createCadet(p, l, f, i, g, r, n);
            System.out.println("[cadet] Cadet created.");
        }
        catch (RuntimeException e)
        {
            System.out.println("[error] Syntax error.");
            e.printStackTrace();
        }
        
    }
    
    private static void createEvent(String[] args)
    {
        try
        {
            if(findEvent(args) != null) //They found an match, and it returned an event.
            {
                System.out.println("[error] Event already exists!");
                return;
            }
            System.out.println("[create event] Proceeding to create event...");
            String n = args[0];
            Date d = Date.valueOf(args[1]);
            Category c = Category.valueOf(args[2]);
            int t = Integer.parseInt(args[3]);
            admintracker.createEvent(n, d, c, t);
            System.out.println("[event] Event created.");
        }
        catch (RuntimeException e)
        {
            System.out.println("[error] Syntax error.");
            e.printStackTrace();
        }
    }

    private static void getCadets()
    {
        for(Cadet c : admintracker.getCadets())
        {
            System.out.println("[cadet list] " + c.toString());
        }
    }
    
    private static void getEvents()
    {
        for(Event e : admintracker.getEvents())
        {
            System.out.println("[event list] " + e.toString());
        }
    }
    
    private static Cadet findCadet(String[] args)
    {
        String id = args[0];
        id = id.toUpperCase();

        ArrayList<Cadet> cadets = null;
        if(id.matches("\\d{4,}"))
        {
            cadets = admintracker.findCadets(Integer.parseInt(id), "", "");
        }
        else if(id.matches("(\\w|\\s)++"))
        {
            cadets = admintracker.findCadets(-1, id, "");
            cadets.addAll(admintracker.findCadets(-1, "", id));
        }
        
        if(cadets.size() > 1)
        {
            System.out.println("[error] There is more than one cadet that matches that argument.");
            for(Cadet d : cadets)
            {
                System.out.println("[ambiguous cadet] " + d.toString());
            }
        }
        else if(cadets.size() == 1)
        {
            Cadet c = cadets.get(0);
            return c;
        }
        else
        {
            System.out.println("[get cadet] Cadet not found.");
        }
        return null;
    }
    
    private static Event findEvent(String[] args)
    {
        String id = args[0];
        
        ArrayList<Event> events = null;
        if(args.length >= 2)
        {   
            events = admintracker.findEvents(args[0], Date.valueOf(args[1]));
        }
        else if(id.matches("\\d{4}-\\d{2}-\\d{2}")) //matching a date: yyyy-mm-dd
        {
            events = admintracker.findEvents("", Date.valueOf(id));
        }
        else
        {
            events = admintracker.findEvents(id, null);
        }
        
        if(events.size() > 1)
        {
            System.out.println("[error] There is more than one event that matches that argument.");
            for(Event f : events)
            {
                System.out.println("[ambiguous event] " + f.toString());
            }
        }
        else if(events.size() == 1)
        {
            Event e = events.get(0);
            return e;
        }
        else
        {
            System.out.println("[get event] Event not found.");
        }
        return null;
    }
    
    private static void getCadet(Cadet c)
    {
        if(c == null) return;
        System.out.println("[get cadet] Name: " + c.getName() + " | ID: " + c.getID());
        System.out.println("[get cadet] Platoon: " + c.getPlatoon() + " | Grade: " + c.getGrade());
        System.out.println("[get cadet] Gender: " + c.getGender() + " | NS Year: " + c.getNSYear());
        System.out.println("[get cadet] Ribbons: M D D H C U A 4 3 2 1 E A E P P U C D C R O R B S");
        System.out.print  ("[get cadet] Current: ");
        for(int i : c.getRibbons())
        {
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.print  ("[get cadet] Cap    : ");
        for(int i : c.getSemester())
        {
            System.out.print(i + " ");
        }
        System.out.println();
        System.out.println("[get cadet] Event record for " + c.getName());
        for(Event e : admintracker.getEvents())
        {
            int dur = e.get(c.getID());
            if(dur > 0)
                System.out.println("[get cadet] " + e.getName() + ", for " + dur);
        }
    }
    
    private static void getEvent(Event e)
    {
        if(e == null) return;
        System.out.println("[get event] Name: " + e.getName() + " | Date: " + e.getDate());
        System.out.println("[get event] Category: " + e.getCategory().toString()+" | Duration: " + e.getDuration());
        System.out.println("[get event] Roster ID: " + e.getRosterID());
        System.out.println("[get event] Student record for " + e.getName());
        for(Integer i : e.getIDs())
        {
            System.out.println("[get event] " + i + ", " + e.get(i));
        }
    }
    
    private static void removeCadet(Cadet c)
    {
        if(c == null) return;
        System.out.print("[remove] Are you sure you want to remove " + c.toString() + "? (Y|N)> ");
        String command = scanner.nextLine();
        if(command.equals("Y"))
        {
            admintracker.removeCadet(c);
            System.out.println("[remove] Cadet removed.");
        }
    }
    
    private static void removeEvent(Event e)
    {
        if(e == null) return;
        System.out.print("[remove] Are you sure you want to remove " + e.toString() + "? (Y|N)> ");
        String command = scanner.nextLine();
        if(command.equals("Y"))
        {
            admintracker.removeEvent(e);
            System.out.println("[remove] Event removed.");
        }
    }
    
    private static void setRibbon(Cadet c)
    {
        if(c == null) return;
        System.out.println("[ribbon] You are about to enter ribbon information for: " + c.getName() +", " + c.getID());
        for(int i : c.getRibbons())
        {
            System.out.print(i +" ");
        }
        System.out.println("[prompt] Are you sure you want to continue? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            System.out.println("[ribbon] Type out one massive line, separated by spaces.");
            System.out.println("[ribbon] M D D H C U A 4 3 2 1 E A E P P U C D C R O R B S");
            System.out.print("[ribbon] ");
            String line = scanner.nextLine();
            StringTokenizer stk = new StringTokenizer(line);
            int[] vals = new int[25];
            for(int i = 0; i < vals.length; i++)
            {
                if(stk.hasMoreElements())
                {
                    String val = stk.nextToken();
                    if(val.matches("\\d{1,}"))
                        vals[i] = Integer.parseInt(val) + 1;
                    else if(val.equals("`"))
                        vals[i] = 0;
                    else vals[i] = 0;
                }
                else
                {
                    vals[i] = 0;
                }
                
            }
            c.setRibbons(vals);
            System.out.println("[ribbon] Ribbons set for " + c);
        }
    }
    
    private static void setRibbon(String[] args)
    {
        if(args.length >= 26) //26 would be the length of the ribbon array.
        {
            String[] cadetGet = { args[0] };
            int[] vals = new int[25];
            for(int idx = 1; idx < 26; idx++)
            {
                vals[idx - 1] = Integer.parseInt(args[idx]);
            }
            Cadet c = findCadet(cadetGet);
            if(c != null)
            {
                c.setRibbons(vals);
            }
        }
        else
        {
            System.out.println("[error] Syntax error for ribbon entry.");
        }
    }
    
    private static void input(Event e)
    {
        if(e == null) return;
        System.out.print("[input] Are you sure that " + e.toString() + " is correct? (Y|N)> ");
        String command = scanner.nextLine();
        if(command.equals("Y"))
        {
            boolean oneTimeForAll = false;
            int constantTime = 1;
            boolean isService = e.getCategory().equals(Category.US) || e.getCategory().equals(Category.CS);
            if(isService)
            {
                System.out.print("[input] You have selected a service event. Do you want to input" +
                        " the same time for all persons? (Y|N)> ");
                oneTimeForAll = scanner.nextLine().equals("Y");
                if(oneTimeForAll)
                {
                    boolean successful = false;
                    while(!successful)
                    {
                        System.out.print("[prompt] Time?> ");
                        String parse = scanner.nextLine();
                        if(parse.matches("\\d{1,}"))
                        {
                            constantTime = Integer.parseInt(parse);
                            successful = true;
                        }
                        else
                        {
                            System.out.println("[error] That was not a number.");
                        }
                    }
                }
                    
            }
            System.out.println("[input] Type STOP to end input.");
            boolean stopped = false;
            int undo = -1;
            while(!stopped)
            {
                System.out.print("[input] Cadet name/ID?> ");
                String line = scanner.nextLine();
                if(line.toUpperCase().equals("STOP")) break;
                if(line.toUpperCase().equals("UNDO"))
                {
                    if(undo > 0)
                    {
                        e.rem(undo);
                        System.out.println("[input] Undo performed for " + undo);
                        undo = -1;
                    }
                }
                else
                {
                    String[] arg = { line };
                    Cadet c = findCadet(arg);
                    if(c != null)
                    {
                        if(isService)
                        {
                            if(oneTimeForAll)
                            {
                                e.set(c, constantTime);
                            }
                            else
                            {
                                boolean successful = false;
                                while(!successful)
                                {
                                    System.out.print("[input] Time?> ");
                                    String parse = scanner.nextLine();
                                    if(parse.matches("\\d{1,}"))
                                    {
                                        int time = Integer.parseInt(parse);
                                        e.set(c.getID(), time);
                                        successful = true;
                                    }
                                    else
                                    {
                                        System.out.println("[error] That was not a number.");
                                    }
                                }
                            }
                        }
                        else
                        {
                            e.set(c, 1);
                        }
                        undo = c.getID(); //if the cadet had a time set, we're
                                          //setting up the possibility for undo.
                    }
                }
            }
        }
        System.out.println("[input] Input terminated.");
    }
    
    private static void insert(String[] args)
    {
        //to be in order of EVENT,CADET,TIME.
        if(args.length < 3)
        {
            System.out.println("[error] Insert syntax error.");
            return;
        }
        try
        {
            String[] eventGet = { args[0] };
            String[] cadetGet = { args[1] };
            int hourGet = Integer.parseInt(args[2]);
            Event e = findEvent(eventGet);
            Cadet c = findCadet(cadetGet);
            if(e == null || c == null)
            {
                System.out.println("[error] Event or cadet not found.");
                return;
            }
            e.set(c,hourGet);
        }
        catch (RuntimeException e)
        {
            System.out.println("[error] Insert syntax error.");
            return;
        }
    }

    private static void outputAwards()
    {
        System.out.println("[output] You are about to output awards.");
        System.out.println("[output] This will do a transaction that");
        System.out.println("[output] will recalculate the caps, which");
        System.out.println("[output] will make records different");
        System.out.println("[output] even if you output them again.");
        System.out.println("[output] If you only want to view what WOULD happen,");
        System.out.println("[output] please use previewAwards instead.");
        System.out.print  ("[output] Are you sure you want to continue? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            ArrayList<Object[]> output = admintracker.transactAwards(); //do not write this. only read.
            printOutput(output, System.out);
            System.out.println("[output] Dumping to file...");
            long time = System.currentTimeMillis();
            dumpOutput(output, time + "award");
            dumpRibbons(time + "ribbons");
            System.out.println("[output] Complete.");
        }
    }
    
    private static void previewAwards()
    {
        System.out.println("[preview] You are about to preview awards.");
        System.out.println("[preview] This is a developer's feature that allows");
        System.out.println("[preview] you to determine how much to award without");
        System.out.println("[preview] actually changing cadet information.");
        System.out.print  ("[preview] Are you sure you want to continue? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {
            ArrayList<Object[]> output = admintracker.previewAwards();
            printOutput(output, System.out);
            System.out.println("[preview] Dumping to file...");
            long time = System.currentTimeMillis();
            dumpOutput(output, time + "preview");
            dumpRibbons(time + "ribbons");
            System.out.println("[preview] Complete.");
        }
    }
    
    private static void printOutput(ArrayList<Object[]> output, PrintStream out)
    {
        System.out.println("[output] How do you want the awards organized?");
        System.out.println("[output] By: 1)Cadet 2)Platoon 3)Category 4)Device");
        System.out.print  ("[output] Number? (1-4)> ");
        int choice = 0;
        boolean successful = false;
        while(!successful)
        {
            String parse = scanner.nextLine();
            if(parse.matches("\\d{1,}"))
            {
                choice = Integer.parseInt(parse);
                successful = true;
            }
            else
            {
                System.out.println("[error] That was not a number.");
            }
        }

        if(choice == 1)
        {
            out.println("[output] Organizing by cadet.");
            for(Cadet c : admintracker.getCadets())
            {
                out.println("[output] RECORD FOR: " + c.getName());
                for(Object[] entry : output)
                {
                    if(c.equals(entry[0]))
                    {
                        int value = ((Integer)entry[2]) + ((Integer)entry[3]);
                        if(value < 0) value = 0;
                        if(value > 7) value = 7;
                        out.println("["+c.getName()+"] " + 
                                ((Category)entry[1]).toString() + ", " + AdminTracker.RIBBON_TITLES[value]);
                    }
                }
                out.println();
            }
        }
        else if(choice == 2)
        {
            out.println("[output] Organizing by platoon.");
            int maxPlatoon = 0;
            for(Cadet c : admintracker.getCadets())
                maxPlatoon = Math.max(maxPlatoon, c.getPlatoon());
            for(int i = 0; i <= maxPlatoon; i++)
            {
                out.println("[output] RECORD FOR: " + i + " PLATOON");
                for(Object[] entry : output)
                {
                    if(((Cadet)entry[0]).getPlatoon() == i)
                    {
                        int value = ((Integer)entry[2]) + ((Integer)entry[3]);
                        if(value < 0) value = 0;
                        if(value > 7) value = 7;
                        out.println("[" + i + " PLATOON] "+((Cadet)entry[0]).getName()+
                                " EARNED " + ((Category)entry[1]).toString() + ", " + AdminTracker.RIBBON_TITLES[value]);
                    }
                }
                out.println();
            }
        }
        else if(choice == 3)
        {
            out.println("[output] Organizing by category.");
            for(Category c : Category.values())
            {
                out.println("[output] RECORD FOR CATEGORY: " + c.getCategory() + "(" + c.toString() + ")");
                for(Object[] entry : output)
                {
                    if(c.equals(entry[1]))
                    {
                        int value = ((Integer)entry[2]) + ((Integer)entry[3]);
                        if(value < 0) value = 0;
                        if(value > 7) value = 7;
                        out.println("[" + c.getCategory() + "] " + ((Cadet)entry[0]).getName()+
                                " EARNED " + AdminTracker.RIBBON_TITLES[value]);
                    }
                }
                out.println();
            }
        }
        else if(choice == 4)
        {
            out.println("[output] Organizing by award devices.");
            for(int level = 0; level <= 7; level++)
            {
                out.println("[output] RECORD FOR " + AdminTracker.RIBBON_TITLES[level]);
                for(Object[] entry : output)
                {
                    int value = ((Integer)entry[2]) + ((Integer)entry[3]);
                    if(value < 0) value = 0;
                    if(value > 7) value = 7;
                    if(level == value)
                    {
                        out.println("[" + AdminTracker.RIBBON_TITLES[level] + "] " + ((Cadet)entry[0]).getName()+
                                " EARNED " + ((Category)entry[1]).toString());
                    }
                }
                out.println();
            }
        }
        out.println("[output] Award output complete.");
    }
    
    private static void dumpOutput(ArrayList<Object[]> output, String filename)
    {
        System.out.println("[dump output] Dumping output to: " + filename);
        File name = new File(OUTPUT + SEPARATOR + filename + ".ato");
        try 
        {
            name.createNewFile();
            String date = (new java.util.Date()).toString();
            PrintStream writer = new PrintStream(new FileOutputStream(name));
            writer.println("---------------------------------");
            writer.println("----ADMINTRACKER AWARD OUTPUT----");
            writer.println("FOR: " + date); //date variable is 28 characters
            writer.println("---------------------------------");
            writer.println("THIS FILE CONTAINS ALL RECORDS AS");
            writer.println("FAR AS THE SYSTEM KNOWS TO DATE");
            writer.println("---------------------------------");
            printOutput(output, writer);
            writer.println("Output completed.");
            writer.close();
        } 
        catch (IOException ex)
        {
            System.out.println("[error] File dump failed.");
        }
        
    }
    
    //really just a convenience method to determine roster id's by hand.
    private static void convertDate(String[] args)
    {
        if(args.length >= 1 && !args[0].equals(""))
        {
            if(args[0].matches("\\d{1,}"))
            {
                System.out.println("[convert date] Long version: " + args[0] + ", Real version: " + (new java.util.Date(Integer.parseInt(args[0])).toString()));               
            }
            else if(args[0].matches("\\d{4}-\\d{2}-\\d{2}"))
            {
                System.out.println("[convert date] Long version: " + Date.valueOf(args[0]).getTime() + ", Real version: " + args[0]);               
            }
            else
            {
                System.out.println("[error] Date format not recognized.");
            }
        }
    }
    
    private static void dumpRibbons(String filename)
    {
        System.out.println("[dump ribbons] Dumping ribbons to: " + filename);
        File name = new File(OUTPUT + SEPARATOR + filename + ".ato");
        try 
        {
            name.createNewFile();
            String date = (new java.util.Date()).toString();
            PrintStream writer = new PrintStream(new FileOutputStream(name));
            writer.println("---------------------------------");
            writer.println("ADMINTRACKER RIBBON RECORD OUTPUT");
            writer.println("FOR: " + date);
            writer.println("---------------------------------");
            writer.println("THIS FILE CONTAINS ALL RECORDS AS");
            writer.println("FAR AS THE SYSTEM KNOWS TO DATE");
            writer.println("---------------------------------");
            writer.println();
            for(Cadet c : admintracker.getCadets())
            {
                writer.println("RECORDS FOR " + c.getName());
                writer.println("KEY   : M D D H C U A 4 3 2 1 E A E P P U C D C R O R B S");
                writer.print  ("RIBBON: ");
                for(int i : c.getRibbons())
                {
                    writer.print(i + " ");
                }
                writer.println();
                writer.print  ("CAP   : ");
                for(int i : c.getSemester())
                {
                    writer.print(i + " ");
                }
                writer.println();
                writer.println();
            }
            writer.println("Output completed.");
            writer.close();
        } 
        catch (IOException ex)
        {
            System.out.println("[error] File dump failed.");
        }            
    }
    
    private static void dumpEvents(String filename)
    {
        System.out.println("[dump events] Dumping events to: " + filename);
        File name = new File(OUTPUT + SEPARATOR + filename + ".csv");
        try 
        {
            name.createNewFile();
            ArrayList<Event> allEvents = admintracker.getEvents();
            ArrayList<Cadet> allCadets = admintracker.getCadets();
            PrintStream writer = new PrintStream(new FileOutputStream(name));
            writer.println("ADMINTRACKER EVENT RECORD OUTPUT,"+new java.util.Date().toString());
            writer.print("EVENT > STUDENT \\/,,,"); //this shift allows for lining up
            for(Event e : allEvents)
            {
                writer.print(e.getName() + ": " + e.getDate() + " ("+e.getCategory().toString()+"),");
            }//prints the first line.
            writer.println();
            for(Cadet c : allCadets)
            {
                writer.print(c.getID() + "," + c.getName() +",");
                for(Event e : allEvents)
                {
                    writer.print(e.get(c.getID()) +",");
                }
                writer.println();
            }
            writer.println("Last Entry.");
            writer.close();
        } 
        catch (IOException ex)
        {
            System.out.println("[error] File dump failed.");
        }    
    }
    
    private static void resetSemester()
    {
        System.out.println("[reset semester] You are about to reset the semester cap records.");
        System.out.println("[reset semester] You should only perform this action ONCE at the");
        System.out.println("[reset semester] beginning of a semester. Repetitive use of this");
        System.out.println("[reset semester] command will ruin records.");
        System.out.println("[reset semester] Are you sure you want to continue? (Y|N)> ");
        boolean go = scanner.nextLine().equals("Y");
        if(go)
        {  
            int[] reset = new int[25];
            for(int idx = 0; idx < reset.length; idx++)
            {
                reset[idx] = 0;
            }
            for(Cadet c : admintracker.getCadets())
            {
                c.setSemester(reset);
            }
        }
        System.out.println("[reset semester] Semester cap reset complete.");
    }
}